<?php
  
namespace App\Utils;

use App\Utils\CRC16;
use Cache;

class DeviceServer
{
    /**
     * 格式化设备发送的数据d
     * @param  [type] $data 
     * @return [type]
     */
    public static function dataFormat($dataCmd, $data)
    {
        try{
            $formatData = [];
            switch ($dataCmd) {
                case 0x0001:
                    $unpackData = unpack('Nhead/CdataLength/NmessageNumber/N2deviceCode/CdataCommand/CdecStatus', $data);
                    $formatData['decStatus'] = $unpackData["decStatus"] & 0x0f; //工作状态
                    $formatData['decStatusDescription'] = config("heting.decStatus.$formatData[decStatus]");
                    break;
                case 0x0002:
                    $unpackData = unpack('Nhead/CdataLength/NmessageNumber/N2deviceCode/CdataCommand/n2TDS', $data);
                    $formatData['TDS1'] = str_pad($unpackData["TDS1"], 3,"0",STR_PAD_LEFT); //原水 TDS
                    $formatData['TDS2'] = str_pad($unpackData["TDS2"], 3,"0",STR_PAD_LEFT);; //纯水 TDS
                    break;
                case 0x0003:
                    $unpackData = unpack('Nhead/CdataLength/NmessageNumber/N2deviceCode/CdataCommand/n5filterSet/n5filterCnt', $data);
                    //滤芯
                    for ($i=1; $i<=5; $i++)
                    {
                        if($unpackData["filterSet$i"] != 0)
                        {
                            $formatData["filter$i"] = 100 - round($unpackData["filterCnt$i"] / $unpackData["filterSet$i"], 2) * 100;
                        }
                        else
                        {
                            $formatData["filter$i"] = 0;
                        }
                        $formatData["filterCnt$i"] = $unpackData["filterCnt$i"];
                        $formatData["filterSet$i"] = $unpackData["filterSet$i"];
                    }
                    break;
                case 0x0004:
                    $unpackData = unpack('Nhead/CdataLength/NmessageNumber/N2deviceCode/CdataCommand/n2flow', $data);
                    //总流量
                    $formatData['totalFlow' ]= $unpackData['flow1'];//str_pad($waterCnt, 6, "0", STR_PAD_LEFT);
                    //剩余流量
                    $formatData['residualFlow'] = $unpackData['flow2'];
                    break;
                default:
                    $unpackData = unpack('Nhead/CdataLength/NmessageNumber/N2deviceCode/CdataCommand', $data);
                    break;
            }
            //设备码
            $d1 = ($unpackData["deviceCode1"]>>24)&255;//年,
            $d10 = ($unpackData["deviceCode1"]>>16)&255;//年,
            $d11 = ($unpackData["deviceCode1"]>>8)&255;//月
            $d2 = $unpackData["deviceCode1"]&255;//日

            //转为显示设备码形式
            $formatData['deviceCode'] = substr(strval($d1 + 100), 1, 2);
            $formatData['deviceCode'] .= substr(strval($d10 + 100), 1, 2);
            $formatData['deviceCode'] .= substr(strval($d11 + 100), 1, 2);
            $formatData['deviceCode'] .= substr(strval($d2 + 100), 1, 2);
            $formatData['deviceCode'] .= substr(strval($unpackData["deviceCode2"] + 100000000), 1, 8);
            $formatData['messageNumber'] = $unpackData['messageNumber'];
            return $formatData;
        }catch(Exception $e){
            logger(['Device@dataFormat' => [
                'line' => $e->getLine(),
                'message' => $e->getMessage(),
                ]]);
        }
    }

    public static function getCmdByte($binDeviceCode, $dataLen, $dataCmd, $conEn, $conExt = 0, $orderId = null, $operation = 0)
    {
        $deviceCode = self::getDeviceCode($binDeviceCode);
        if($dataCmd == 0x0a && Cache::has($deviceCode.'haltMessage'.$conEn)){
            $haltMessage = Cache::get($deviceCode.'haltMessage'.$conEn);
            Cache::put($deviceCode.'haltMessage'.$conEn, $haltMessage, 1);
            $binaryData = $haltMessage['binaryData'];
        }else{
            if(is_null($orderId)){
                $messageNumber = Cache::remember($deviceCode.'messageNumber', 60*24*7, function(){
                    return 1;
                });
            }else{
                $messageNumber = $orderId;
            }
            $binaryData = pack("n2CN", 0xbb00, 0x0780, $dataLen, $messageNumber).$binDeviceCode;
            
            switch ($dataCmd) {
                case 0x07:
                    $binaryData .= pack('C3', 0x07, $conEn, $conExt);
                    break;
                case 0x08:
                    $conEn&=0x00ffffff;
                    $conEn|=$operation;
                    $binaryData .= pack('CN', 0x08, $conEn);
                    break;
                case 0x0a:
                    $binaryData .= pack('C2', 0x0a, $conEn);
                    $haltMessage = [
                        'conExt' => $conEn,
                        'messageNumber' => $messageNumber,
                        'binaryData' => $binaryData,
                    ];
                    Cache::put($deviceCode.'haltMessage'.$conEn, $haltMessage, 1);
                    break;
                default:
                    # code...
                    break;
            }

            is_null($orderId) ? Cache::put($deviceCode.'messageNumber', ++$messageNumber, 60*24*7) :'';
        }
        $crc = CRC16::crc16($binaryData);
        $binaryData1 = pack("n",$crc);
        $binaryData.=$binaryData1;
        return $binaryData;
    }

    public static function getDeviceCode($data)
    {
        $deviceCode = '';
        foreach(unpack('C8', $data) as $value){
            $deviceCode .= substr(strval($value + 100), 1, 2);
        }
        return $deviceCode;
    }

}